/*
 * Copyright 2004-2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package susano.presen.util;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.json.simple.JSONValue;

import susano.common.exception.SusanoRuntimeException;

/**
 * ダウンロードユーティル
 *
 * @author tanaka.akira
 * @version $Id: DownloadUtil.java 617 2009-10-21 10:21:20Z tanaka.akira.2006 $
 */
public final class DownloadUtil {

	/*
	 * CONTENT-TYPE
	 */
	/** text/html */
	public static final String CONTENT_TYPE_TEXTHTML = "text/html;charset=";
	/** application/octet-stream */
	public static final String CONTENT_TYPE_OCTETSTREAM = "application/octet-stream;charset=";

	private static final String DEFAULT_CHARSET = "UTF-8";

	/*
	 * レスポンスヘッダーキー
	 */
	private static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition";
	private static final String HEADER_EXPIRES = "Expires";
	private static final String HEADER_CACHE_CONTROL = "Cache-Control";
	private static final String HEADER_PRAGMA = "Pragma";

	/** ダウンロードファイル名のエンコード */
	private static final String DEFAULT_ATTACHMENTS_FILENAME_ENCODING = "ISO-8859-1";

	/**
	 * オブジェクトをJSON文字列にしてダウンロードします。
	 *
	 * @param request
	 * @param response
	 * @param object
	 */
	public static final void downloadJSON(HttpServletRequest request,
			HttpServletResponse response, Object object) {
		downloadJSON(request, response, object, DEFAULT_CHARSET);
	}

	/**
	 * オブジェクトをJSON文字列にしてダウンロードします。
	 *
	 * @param request
	 * @param response
	 * @param object
	 * @param charset
	 */
	public static final void downloadJSON(HttpServletRequest request,
			HttpServletResponse response, Object object, String charset) {
		PrintWriter pw = null;
		try {
			request.setCharacterEncoding(charset);
			response.setContentType(CONTENT_TYPE_TEXTHTML + charset);
			pw = response.getWriter();
			JSONValue.writeJSONString(object, pw);
		} catch (IOException e) {
			throw new SusanoRuntimeException(e);
		} finally {
			IOUtils.closeQuietly(pw);
		}
	}

	/**
	 * ファイル名をつけてdataをダウンロードします。
	 *
	 * @param request
	 * @param response
	 * @param data
	 * @param filename
	 */
	public static final void download(HttpServletRequest request,
			HttpServletResponse response, InputStream data,
			final String filename) {
		download(request, response, data, filename, DEFAULT_CHARSET);
	}

	/**
	 * ファイル名をつけてdataをダウンロードします。
	 *
	 * @param request
	 * @param response
	 * @param data
	 * @param filename
	 * @param charset
	 */
	public static final void download(HttpServletRequest request,
			HttpServletResponse response, InputStream data,
			final String filename, String charset) {
		OutputStream out = null;
		try {
			request.setCharacterEncoding(charset);
			response.setContentType(CONTENT_TYPE_OCTETSTREAM + charset);
			response.setHeader(HEADER_CONTENT_DISPOSITION, String.format(
					"attachments; filename=\"%s\"", new String(filename
							.getBytes(DEFAULT_CHARSET),
							DEFAULT_ATTACHMENTS_FILENAME_ENCODING)));
			response.setHeader(HEADER_EXPIRES, "0");
			response
					.setHeader(HEADER_CACHE_CONTROL,
							"private, no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
			response.setHeader(HEADER_PRAGMA, "private");
			out = new BufferedOutputStream(response.getOutputStream());
			IOUtils.copy(data, out);
			out.flush();
		} catch (IOException e) {
			throw new SusanoRuntimeException(e);
		} finally {
			IOUtils.closeQuietly(out);
		}
	}
}
